{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# Py3_Demo_Jupyter_Scikit-Learn简单线性回归(SimpleLinearRegression)用例_2023-07-29.ipynb\n",
    "# Create By GF 2023-07-29 00:42"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# 导入 Numpy 库 : 用于计算方差、协方差。\n",
    "import numpy as np\n",
    "\n",
    "# 导入 Matplotlib 库 : 用于图形化呈现。\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 导入一元线性回归函数 : y = α + βx。\n",
    "from sklearn.linear_model import LinearRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "plt.rcParams[\"font.sans-serif\"]=[\"SimHei\"] # -> 设置字体，解决图像中中文乱码问题。\n",
    "plt.rcParams[\"axes.unicode_minus\"]=False # -> 关闭负号默认解码，解决图像中的“-”负号的乱码问题。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# 预测披萨的价格，数据如下：\n",
    "\n",
    "Table = \"\"\"\n",
    "+---------+-----------+-----------+\n",
    "|训练样本 |直径(英寸) |价格(美元) |\n",
    "+---------+-----------+-----------+\n",
    "|1        |6          |7          |\n",
    "|2        |8          |9          |\n",
    "|3        |10         |13         |\n",
    "|4        |14         |17.5       |\n",
    "|5        |18         |18         |\n",
    "+---------+-----------+-----------+\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# 训练集数据。\n",
    "\n",
    "x = [[6], [8], [10], [14], [18]]\n",
    "\n",
    "y = [[7], [9], [13], [17.5], [18]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# 将一元线性回归模型定义到 model 变量中。\n",
    "\n",
    "model = LinearRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LinearRegression()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">LinearRegression</label><div class=\"sk-toggleable__content\"><pre>LinearRegression()</pre></div></div></div></div></div>"
      ],
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将训练集数据放入模型中。\n",
    "\n",
    "model.fit(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "披萨的直径 (X) 为 12 时，披萨的价格 (y) 为 : 13.68 美元\n"
     ]
    }
   ],
   "source": [
    "# 当披萨的直径为 12 英寸时，预测披萨的价格。\n",
    "\n",
    "print(\"披萨的直径 (X) 为 12 时，披萨的价格 (y) 为 : %.2f 美元\" % model.predict([[12]])) # -> model.predict() 中的参数应为 2D 数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.96551724]\n",
      " [11.72844828]\n",
      " [15.63362069]\n",
      " [26.37284483]]\n"
     ]
    }
   ],
   "source": [
    "# 定义一组 x2 数据，并预测一组 y2 数据。\n",
    "\n",
    "x2 = [[0],[10],[14],[25]]\n",
    "\n",
    "y2 = model.predict(x2)\n",
    "\n",
    "print(y2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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0RowYIAWLFigxx57TOPHj1dOTk6RP9/PP/+sJk2aOO+fPn1ad9xxh3755RedPn1atWrV0i+//OJ8/t5779WBAweKPX779+9X/fr1i9wuIyNDTz31lJo1a6azZ88qIiJCf/zjH3XvvfdKkipWrKjJkyfro48+0qxZsyRJiYmJatWqlbp06aI5c+YoOjpaGzdu1Kuvvqr+/ftrzJgxqlChQrHqvHjxokJDQxUYeOmta+/evbrzzjudz7/11lt65plnnPdbt26tHTt2FGvfl/d5WVpammbPnl3gUkRubq7zEkSlSpW0Z88epaSkKDk5We+++666deum5ORkJScnKyUlRZMnTy6wz6SkJI0bN045OTlq3769GjZsqKioKH311Vfq0KFDseoEbhTX6GE5x44dU7Vq1ZSbm6uqVavq9ttvV7ly5fTGG2/omWee0dixYyVdCqW6desqMDBQnTt3VufOnXXo0CH17dtX99xzjx5++GGtX7++wLXlwMBAxcfHa9myZQWOefLkScXGxjrv5+TkaMSIEZo1a5a++OILLVq0SLfffrs2b97s3N/69es1bdo0ZWdnKzg4uNCfKTU1VZUrV3ber1atmsaMGaOxY8cqLCxMzz33nOrUqeN8vnLlykpNTS32mAUHB2v8+PEaP378Vc+dPn1aNptNs2fP1unTp/XEE0/oyJEjqlKlir788kvt2rVLkydP1rvvvqvvvvtOH330kb7++mtncJ48eVLr169X7dq1NXLkSM2fP1/bt29XxYoVdejQIf300086fvy4atSoUWSdV47D3XffrZCQECUnJ+u+++7T559/rn/+858lHoffuvXWW7Vo0SKNHj1aY8aMUY0aNa6aq1CUnJwclSlTxjkWkZGRmj17tubOnavOnTtr1KhRqlixoubMmaPFixfr/fffd857AFyFoIclHD16VJ9//rlSUlI0ZcoUvfvuuzLG6Nlnn1WrVq30yCOPqEuXLoqJiSnwuipVqigzM1MnTpzQoEGDdPbsWe3YsUNpaWlKTU1Vu3bt9OKLL6p79+7O19x///1X7ScxMbHA/b1796pGjRrq16+fJKlz587q2bOnpk+froCAAEmXJrl16dJFlSpVKvLnq1q1qs6cOVPgsUGDBmn27Nm6ePGikpKSCjx3+vRpVa1atcj9XjZjxozrPvfaa685v2JWv359jRkzRoMH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",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 1. 定义数据。\n",
    "\n",
    "# 1.1 复制上面训练集的数据。\n",
    "\n",
    "x1 = [[6], [8], [10], [14], [18]]\n",
    "\n",
    "y1 = [[7], [9], [13], [17.5], [18]]\n",
    "\n",
    "# 1.2 复制上面定义的一组 x2 的数据和预测的一组 y2 的数据。\n",
    "\n",
    "x2 = [[0],[10],[14],[25]]\n",
    "\n",
    "y2 = model.predict(x2)\n",
    "\n",
    "# 2. 绘制图像。\n",
    "\n",
    "# 2.1 定义画板、绘图轴区域、标题、标签。\n",
    "\n",
    "fig = plt.figure(figsize=(8, 6), dpi=72)\n",
    "ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])\n",
    "ax.set_title(\"披萨直径 (x) 与价格 (y) 的关系\")\n",
    "ax.set_xlabel(\"直径 (英寸)\")\n",
    "ax.set_ylabel(\"价格 (美元)\")\n",
    "ax.grid(True)\n",
    "\n",
    "# 2.2 绘制实际数据。\n",
    "\n",
    "ax.plot(x1, y1, 'k.')\n",
    "\n",
    "# 2.3 根据输入的 x2 的值和预测的 y2 的值绘制一条直线。\n",
    "\n",
    "ax.plot(x2, y2, 'g-')\n",
    "\n",
    "# 3. 残差预测值。\n",
    "\n",
    "# 3.1 根据 x1 求出 y1 的预测值，以便于和实际值做对比。\n",
    "y1p = model.predict(x1)\n",
    "\n",
    "# 3.2 for 循环方法用红线标示出预测值与实际值之间的差值。\n",
    "for x, r, p in zip(x1, y1, y1p):\n",
    "    ax.plot([x, x], [r, p], \"r-\")\n",
    "\n",
    "# 3.3 enumerate 方法用红线标示出预测值与实际值之间的差值。\n",
    "#y1p = model.predict(x1)\n",
    "#for i, x in enumerate(x1):\n",
    "#    ax.plot([x, x], [y1[i], y1p[i]], 'r-')\n",
    "\n",
    " \n",
    "# 显示上一个画布。\n",
    "plt.show()\n",
    "# 关闭上一个画布。\n",
    "plt.close(fig)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 方差 ] : 23.20\n",
      "[ 协方差 ] : 22.65\n",
      "[ 一元线性方程 ] : y = -4.67 x - 0.98\n"
     ]
    }
   ],
   "source": [
    "# 解一元线性方程 (最小二乘法 )。\n",
    "\n",
    "# LinearRegression 类的 fit() 方法学习下面的一元线性回归模型 : y = α + βx\n",
    "# β = cov(x, y) / var(x) : (协方差 / 方差) : α = y¯ − βx¯\n",
    "\n",
    "# numpy.var() 方法 ：计算一组数据的方差。\n",
    "var = np.var([6, 8, 10, 14, 18], ddof=1) # -> 计算中使用的除数为 N - ddof，ddof 默认为 0。\n",
    "\n",
    "print(\"[ 方差 ] : %.2f\" % var)\n",
    "\n",
    "cov = np.cov([6, 8, 10, 14, 18], [7, 9, 13, 17.5, 18])[0][1]\n",
    "\n",
    "print(\"[ 协方差 ] : %.2f\" % cov)\n",
    "\n",
    "b = cov / var\n",
    "\n",
    "a = np.mean(y) - b * np.mean(x)\n",
    "\n",
    "print (\"[ 一元线性方程 ] : y = %.2f x - %.2f\" % (a, b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ R方 ] : 0.66\n"
     ]
    }
   ],
   "source": [
    "# 评估这个模型的预测准确度。\n",
    "\n",
    "# 模型评估 : R方 也叫确定系数，表示模型对现实数据的拟合程度。一定是介于 0 - 1 之间的数。\n",
    "\n",
    "# 引入测试集。\n",
    "\n",
    "x_test = [[8], [9], [11], [16], [12]]\n",
    "\n",
    "y_test = [[11], [8.5], [15], [18], [11]]\n",
    "\n",
    "R2 = model.score(x_test, y_test)\n",
    "\n",
    "print (\"[ R方 ] : %.2f\" % R2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "# EOF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
